package main

import (
	"bufio"
	"encoding/json"
	"fmt"
	"image-pull/client"
	"image-pull/dockerCore"
	"image-pull/proto"
	"io"
	"net"
	"os"
	"sync"
	"time"
)

// 客户端拉取镜像
func dockerPull(ImageListEnv, nodeIp string) (err error) {
	var ImageList []dockerCore.DockerInfo
	if err = json.Unmarshal([]byte(ImageListEnv), &ImageList); err != nil {
		fmt.Println("变量: ImageListEnv 为空,", err)
		return err
	}
	// 创建通道，用于存储镜像信息
	pullChan := make(chan dockerCore.DockerInfo, len(ImageList))
	wg := sync.WaitGroup{}
	for _, i := range ImageList {
		pullChan <- i
	}
	// 开启3个线程，去下载镜像
	wg.Add(3)
	for n := 1; n <= 3; n++ {
		go func(n int) {
			for p := range pullChan {
				if err = p.PullImage(n, nodeIp); err != nil {
					fmt.Printf("下载出错：线程：%d 镜像名称：%s \n 报错：%s", n, p.ImageName, err.Error())
					return
				}
			}
			wg.Done()
		}(n)
	}
	close(pullChan)
	wg.Wait()
	return
}

func main() {
	var (
		err                error
		serverAddr, nodeIp string
	)
	//获取当前节点名称对应的ip地址
	nodeIp = os.Getenv("nodeIp")

	// 连接服务器
	if serverAddr = os.Getenv("serverAddr"); serverAddr == "" {
		serverAddr = "127.0.0.1:30000"
	}

	for {
		client.TcpClient, err = net.Dial("tcp", serverAddr)
		if err != nil {
			fmt.Println("连接报错，等待server启动:", err)
			time.Sleep(2 * time.Second)
			continue
		}
		defer client.TcpClient.Close()
		// 发送注册信息
		client.TcpSend(client.TcpClient, nodeIp)

		// 开始接受来自服务端的指令
		reader := bufio.NewReader(client.TcpClient)
		for {
			recvStr, err := proto.Decode(reader)
			if err != nil {
				if err == io.EOF {
					fmt.Println("读取完毕")
					break
				}
				fmt.Println("解码失败：", err)
				break
			}
			// 根据服务端发送的详细镜像信息拉取镜像
			if err = dockerPull(recvStr, nodeIp); err != nil {
				break
			}
		}
	}
}
